/**
 * Shell command parser for MCP tools
 */

import path from 'path';
import process from 'process';

export interface ParsedCommand {
  command: string;
  args: Record<string, any>;
  flags: string[];
}

/**
 * Parses a shell command format into structured parameters
 */
export function parseShellCommand(commandString: string): ParsedCommand | null {
  const trimmed = commandString.trim();
  
  // Handle help flags specially
  if (trimmed === '--help' || trimmed === '-h' || trimmed === 'help') {
    return {
      command: 'help',
      args: {},
      flags: []
    };
  }
  
  // Split command by spaces, but preserve quoted strings
  const parts = trimmed.match(/(?:[^\s"]+|"[^"]*")+/g) || [];
  
  if (parts.length === 0) {
    return null;
  }

  const command = parts[0];
  const args: Record<string, any> = {};
  const flags: string[] = [];

  // Parse arguments and flags
  for (let i = 1; i < parts.length; i++) {
    const part = parts[i];
    
    if (part.startsWith('--')) {
      // Long flag: --flag=value or --flag value
      const equalIndex = part.indexOf('=');
      if (equalIndex > 0) {
        const key = part.substring(2, equalIndex);
        const value = part.substring(equalIndex + 1).replace(/^"|"$/g, '');
        args[key] = value;
      } else {
        const key = part.substring(2);
        // Check if next part is a value
        if (i + 1 < parts.length && !parts[i + 1].startsWith('-')) {
          i++;
          args[key] = parts[i].replace(/^"|"$/g, '');
        } else {
          args[key] = true;
        }
      }
    } else if (part.startsWith('-') && part.length > 1) {
      // Short flag: -f or -f value
      const key = part.substring(1);
      if (i + 1 < parts.length && !parts[i + 1].startsWith('-')) {
        i++;
        args[key] = parts[i].replace(/^"|"$/g, '');
      } else {
        flags.push(key);
      }
    } else {
      // Positional argument - treat as directory for most commands or query for search
      const value = part.replace(/^"|"$/g, '');
      if (command === 'search' || command === 'search_code') {
        if (!args.query) {
          args.query = value;
        } else {
          // Append additional words to the query (for multi-word queries)
          args.query += ' ' + value;
        }
      } else {
        if (!args.directory) {
          args.directory = value;
        }
      }
    }
  }

  return { command: command || '', args, flags };
}

/**
 * Maps shell commands to MCP tool names
 */
export function mapShellCommandToTool(command: string): string | null {
  const commandMap: Record<string, string> = {
    'index': 'index_codebase',
    'index-codebase': 'index_codebase',
    'index_codebase': 'index_codebase',
    'search': 'search_code',
    'search-code': 'search_code',
    'search_code': 'search_code',
    'status': 'get_index_status',
    'get-status': 'get_index_status',
    'get_index_status': 'get_index_status',
    'clear': 'clear_index',
    'clear-index': 'clear_index',
    'clear_index': 'clear_index',
    'verify': 'verify_configuration',
    'verify-config': 'verify_configuration',
    'verify_configuration': 'verify_configuration',
    'config': 'verify_configuration',
    'init': 'init_config',
    'init-config': 'init_config',
    'init_config': 'init_config',
    'help': 'help'
  };

  return commandMap[command.toLowerCase()] || null;
}

/**
 * Converts relative path to absolute path using provided base directory
 */
export function resolveDirectoryPath(dirPath: string, baseCwd?: string): string {
  if (!dirPath) return '';
  
  // If already absolute, return as is
  if (path.isAbsolute(dirPath)) {
    return dirPath;
  }
  
  // Use provided base directory or fall back to process.cwd()
  const baseDir = baseCwd || process.cwd();
  return path.resolve(baseDir, dirPath);
}

/**
 * Converts shell command args to tool-specific parameters
 */
export function convertArgsToToolParams(toolName: string, args: Record<string, any>, baseCwd?: string): Record<string, any> {
  const params: Record<string, any> = {};

  switch (toolName) {
    case 'index_codebase':
      params.directory = args.directory ? resolveDirectoryPath(args.directory, baseCwd) : '';
      params.verbose = args.verbose === true || args.v === true || false;
      break;

    case 'search_code':
      params.query = args.query || '';
      params.max_results = args.max_results || args['max-results'] ? parseInt(args.max_results || args['max-results']) : 10;
      params.min_score = args.min_score || args['min-score'] ? parseFloat(args.min_score || args['min-score']) : 0.7;
      params.categorized_search = args.categorized_search || args['categorized-search'] ? 
        (args.categorized_search === 'true' || args['categorized-search'] === 'true' || args.categorized_search === true || args['categorized-search'] === true) : true;
      params.text_min_score = args.text_min_score || args['text-min-score'] ? parseFloat(args.text_min_score || args['text-min-score']) : undefined;
      params.code_min_score = args.code_min_score || args['code-min-score'] ? parseFloat(args.code_min_score || args['code-min-score']) : undefined;
      if (args.directory_prefix || args['directory-prefix']) {
        params.directory_prefix = args.directory_prefix || args['directory-prefix'];
      }
      break;

    case 'clear_index':
      params.confirm = args.confirm === 'true' || args.confirm === true || false;
      break;

    case 'get_index_status':
      params.verbose = args.verbose === true || args.v === true || false;
      break;

    case 'verify_configuration':
    case 'init_config':
    case 'help':
      // These tools don't need parameters
      break;
  }

  return params;
}